package com.jxtc.enterprise.tenant.service;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jxtc.enterprise.admin.dto.TenantRelatedStoreDTO;
import com.jxtc.enterprise.common.constants.FoodStatus;
import com.jxtc.enterprise.common.entity.Food;
import com.jxtc.enterprise.common.entity.Store;
import com.jxtc.enterprise.common.exception.ModifyFailureException;
import com.jxtc.enterprise.common.mapper.FoodMapper;
import com.jxtc.enterprise.common.mapper.StoreMapper;
import com.jxtc.enterprise.common.vo.PaginationResponseVO;
import com.jxtc.enterprise.tenant.dto.TenantChangeFoodSupplyStateDTO;
import com.jxtc.enterprise.tenant.dto.TenantFoodCreateDTO;
import com.jxtc.enterprise.tenant.dto.TenantFoodUpdateDTO;
import com.jxtc.enterprise.tenant.vo.TenantFoodCreateVO;
import com.jxtc.enterprise.tenant.vo.TenantFoodDetailVO;
import com.jxtc.enterprise.tenant.vo.TenantFoodVO;
import com.jxtc.enterprise.tenant.vo.TenantStoreWithFoodTypeVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class TenantFoodManagementService {

    private final FoodMapper foodMapper;
    private final StoreMapper storeMapper;

    public TenantFoodCreateVO saveFood(TenantFoodCreateDTO dto) {
        // 将前端传递的数据转换成符合要求的餐品信息
        Food food = dtoToFood(dto);

        if (foodMapper.insert(food) <= 0) {
            throw new ModifyFailureException("新增餐品失败，请稍后重试");
        }

        return new TenantFoodCreateVO(food.getId(), food.getName());
    }

    /**
     * 根据关键字或店铺 ID 分页查询指定租户所关联店铺下的餐品信息
     *
     * @param tenantId 指定租户 ID
     * @param keyword  关键字
     * @param storeId  店铺 ID
     * @param current  当前页
     * @param size     每页显示的数量
     * @return 分页查询结果
     */
    public PaginationResponseVO<TenantFoodDetailVO> pageFoodByNameOrStoreId(String tenantId, String keyword, String storeId, int current, int size) {
        Page<Food> page = new Page<>(current, size);

        // 查询与租户关联的店铺的 ID 列表
        // SELECT id FROM store WHERE tenant_id = ? AND del_flag = 0
        LambdaQueryWrapper<Store> storeQueryWrapper = new LambdaQueryWrapper<Store>()
                .eq(Store::getTenantId, tenantId)
                .eq(Store::getDelFlag, false)
                .select(Store::getId);
        Page<TenantRelatedStoreDTO> page2 = new Page<>(current, size);
        Page<TenantRelatedStoreDTO> tenantRelatedStoreBriefs = storeMapper.queryTenantRelatedStores(page2, tenantId);
        // 没有与指定租户关联的店铺时，直接返回空的分页数据
        if (tenantRelatedStoreBriefs.getRecords().isEmpty()) {
            return new PaginationResponseVO<>(0, 1, new ArrayList<>());
        }

        // key为店铺id，value为店铺隶属的租户名
        Map<String, String> storeIdToTenantNameMap = tenantRelatedStoreBriefs.getRecords().stream()
                .collect(Collectors.toMap(TenantRelatedStoreDTO::getStoreId, TenantRelatedStoreDTO::getTenantName));
        LambdaQueryWrapper<Food> wrapper = new LambdaQueryWrapper<Food>()
                .eq(Food::getDelFlag, false);

        if (keyword != null && !keyword.isEmpty()) {
            wrapper.like(Food::getName, keyword);
        }

        if (storeId != null && !storeId.isEmpty()) {
            // 如果查询指定店铺下的餐品，则拼接 store_id 即可
            wrapper.eq(Food::getStoreId, storeId);
        } else {
            // 如果没有指明查询那个店铺下的餐品，则查询所有与该租户关联的店铺下的餐品
            wrapper.in(Food::getStoreId, storeIdToTenantNameMap.keySet());
        }

        Page<Food> result = foodMapper.selectPage(page, wrapper);
        // 使用 FoodVO 的构造方法将数据库中的信息转换成对应的 VO
        List<TenantFoodDetailVO> records = result.getRecords().stream().map(food-> {
            String tenantName = storeIdToTenantNameMap.get(food.getStoreId());
            return new TenantFoodDetailVO(food, tenantName);
        } ).collect(Collectors.toList());

        return new PaginationResponseVO<>(result.getTotal(), result.getCurrent(), records);
    }

    public void updateFoodById(TenantFoodUpdateDTO dto) {
        Food food = dtoToFood(dto);
        food.setId(dto.getFoodId());

        if (foodMapper.updateById(food) <= 0) {
            throw new ModifyFailureException("修改餐品信息失败，请稍后重试");
        }
    }


    /**
     * 租户根据菜品 ID 软删除指定菜品
     *
     * @param foodId   菜品 ID
     * @param tenantId 租户 Id
     */
    public void deleteFoodByIdForTenant(String foodId, String tenantId) {
        Food food = foodMapper.selectById(foodId);
        if (food == null) {
            throw new IllegalArgumentException("ID 为 " + foodId + " 的餐品不存在");
        }

        Store store = storeMapper.selectById(food.getStoreId());
        if (store == null) {
            throw new IllegalArgumentException("ID 为 " + foodId + " 的餐品未关联店铺，请联系管理员排查");
        }

        if (tenantId == null || !tenantId.equals(store.getTenantId())) {
            throw new ModifyFailureException("租户 " + tenantId + " 没有修改该菜品的权限");
        }

        // 菜品 ID 存在且该菜品属于该租户所负责的店铺时，将 del_flag 设置为 1
        deleteFoodById(foodId);
    }


    /**
     * 根据菜品 ID 删除指定菜品（软删除）
     *
     * @param id 菜品 Id
     */
    public void deleteFoodById(String id) {
        if (id == null || id.isEmpty()) {
            throw new IllegalArgumentException("删除餐品时，餐品 ID 不能为空");
        }

        Food food = new Food();
        food.setId(id);
        food.setDelFlag(true);

        if (foodMapper.updateById(food) <= 0) {
            throw new ModifyFailureException("删除餐品失败，请稍后重试");
        }
    }


    /**
     * 根据菜品 ID 和 店铺 ID 修改菜品状态
     */
    public void changeFoodSupplyState(TenantChangeFoodSupplyStateDTO dto, String tenantId) {
        Store store = storeMapper.selectById(dto.getStoreId());
        if (store == null) {
            throw new IllegalArgumentException("ID 为 " + dto.getStoreId() + " 的店铺不存在");
        }

        if (tenantId == null || !tenantId.equals(store.getTenantId())) {
            throw new ModifyFailureException("租户 " + tenantId + "没有权限修改菜品状态");
        }

        Food food = new Food();
        food.setId(dto.getFoodId());

        // 如果新的菜品状态为上架状态，则状态标志置为 1
        if (dto.getNewState()) {
            food.setStatus(FoodStatus.ACTIVE.getStatus());
        } else {
            food.setStatus(FoodStatus.DEACTIVATE.getStatus());
        }

        if (foodMapper.updateById(food) <= 0) {
            throw new ModifyFailureException("修改菜品状态失败，请稍后重试");
        }
    }


    /**
     * 将前端传递的数据转换成符合要求的餐品信息，如金额单位转换，标志位转换
     *
     * @param dto 前端传递的数据
     * @return 符合要求的餐品信息
     */
    private Food dtoToFood(TenantFoodCreateDTO dto) {
        Food food = new Food();
        food.setName(dto.getFoodName());
        food.setImage(dto.getFoodImage());

        // 如果前端传递的店铺 ID 不存在，给出提示信息
        Store store = storeMapper.selectById(dto.getStoreId());
        if (store == null) {
            throw new IllegalArgumentException("店铺 ID 不存在");
        }
        food.setStoreName(store.getName());
        food.setStoreId(dto.getStoreId());

        food.setFoodTypeName(dto.getFoodTypeName());

        // 将前端传递的金额（字符串类型）转换成数字类型，并乘以 100 将价格的单位转换成：分
        BigDecimal storePrice = new BigDecimal(dto.getStorePrice()).multiply(new BigDecimal(100));
        food.setStorePrice(storePrice.intValue());

        food.setSortFlag(dto.getSort());
        food.setDescription(dto.getDescription());

        // 如果当前菜品为上架状态，则状态标志置为 1
        if (dto.getState()) {
            food.setStatus(FoodStatus.ACTIVE.getStatus());
        } else {
            food.setStatus(FoodStatus.DEACTIVATE.getStatus());
        }

        food.setRequired(dto.getRequired());
        food.setSpecification(JSONUtil.toJsonStr(dto.getSpecification()));

        return food;
    }


    /**
     * 根据租户 ID 查询店铺 ID（店铺名称）及店铺中的菜品分类信息
     *
     * @return 店铺 ID 及菜品分类列表
     */
    public List<TenantStoreWithFoodTypeVO> listStoreAndFoodTypes(String tenantId) {
        LambdaQueryWrapper<Store> wrapper = new LambdaQueryWrapper<Store>()
                .eq(Store::getDelFlag, false)
                .eq(Store::getTenantId, tenantId)
                .orderByDesc(Store::getCreateTime);

        List<Store> storeList = storeMapper.selectList(wrapper);
        return storeList.stream().map(store -> {
            String foodTypes = store.getFoodTypes();
            if (foodTypes == null || foodTypes.isEmpty()) {
                foodTypes = "[]";
            }
            List<String> list = JSONUtil.parseArray(foodTypes).toList(String.class);
            return new TenantStoreWithFoodTypeVO(store.getName(), store.getId(), list);
        }).collect(Collectors.toList());
    }


    /**
     * 根据菜品 ID 查询指定菜品信息
     *
     * @param foodId 菜品 ID
     * @return 菜品信息
     */
    public TenantFoodVO queryFoodById(String foodId) {
        Food food = foodMapper.selectById(foodId);
        return new TenantFoodVO(food);
    }
}
